import uuid
import re
from datetime import datetime
from typing import Optional

from pydantic import BaseModel, ConfigDict, Field, validator


class TenantBase(BaseModel):
    id: str = Field(default=None, max_length=32, description="租户ID")
    name: str = Field(default=None, min_length=1, max_length=100, description="租户名称")
    code: str = Field(default=None, min_length=1, max_length=50, description="租户编码")
    create_at: datetime = Field(default_factory=datetime.now, description="创建时间")
    update_at: datetime = Field(default_factory=datetime.now, description="更新时间")


class TenantCreate(TenantBase):
    domain: Optional[str] = Field(None, max_length=100, description="租户域名")
    max_users: int = Field(100, description="最大用户数")
    expire_at: Optional[datetime] = Field(None, description="过期时间")
    
    @validator('code')
    def validate_code(cls, v):
        if v is None:
            raise ValueError('租户编码不能为空')
        if not re.match(r'^[a-zA-Z][a-zA-Z0-9]*$', v):
            raise ValueError('租户编码只能以英文字母开头，后面可以跟英文字母或数字')
        return v


class TenantUpdate(BaseModel):
    name: Optional[str] = Field(None, min_length=1, max_length=100, description="租户名称")
    domain: Optional[str] = Field(None, max_length=100, description="租户域名")
    is_active: Optional[bool] = Field(None, description="激活状态")
    max_users: Optional[int] = Field(None, description="最大用户数")
    expire_at: Optional[datetime] = Field(None, description="过期时间")
    update_at: datetime = Field(default_factory=datetime.now, description="更新时间")

class TenantInDBBase(TenantBase):
    id: str
    domain: Optional[str] = None
    is_active: bool
    max_users: int
    expire_at: Optional[datetime] = None
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class Tenant(TenantInDBBase):
    pass


class TenantInDB(TenantInDBBase):
    pass

class TenantQuery(BaseModel):
    """
    租户查询参数模型
    """
    skip: int = 0
    limit: int = 100
    code: Optional[str] = None
    name: Optional[str] = None
    domain: Optional[str] = None
    is_active: Optional[bool] = None